/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.ems.web;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.constant.Constant;
import com.thinkgem.jeesite.common.persistence.BaseEntity;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.utils.CookieUtils;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.modules.ems.entity.Course;
import com.thinkgem.jeesite.modules.ems.entity.Join;
import com.thinkgem.jeesite.modules.ems.service.CourseService;
import com.thinkgem.jeesite.modules.ems.service.JoinService;
import com.thinkgem.jeesite.modules.sys.entity.Mdict;
import com.thinkgem.jeesite.modules.sys.service.DictService;
import com.thinkgem.jeesite.modules.sys.service.MdictService;
import com.thinkgem.jeesite.modules.sys.utils.DictUtils;

/**
 * 报名管理Controller
 * @author zad
 * @version 2017-10-16
 */
@Controller
@RequestMapping(value = "${adminPath}/ems/join")
public class JoinController extends BaseController {

	@Autowired
	private JoinService joinService;
	@Autowired
	private CourseService courseService;
	@Autowired
	private MdictService mdictService;
	
	@Autowired
	private DictService dictService;
	
	@ModelAttribute
	public Join get(@RequestParam(required=false) String id) {
		Join entity = null;
		if (StringUtils.isNotBlank(id)){
			entity = joinService.get(id);
		}
		if (entity == null){
			entity = new Join();
		}
		return entity;
	}
	
	@RequiresPermissions("ems:join:view")
	@RequestMapping(value = {"list", ""})
	public String list(Join join, HttpServletRequest request, HttpServletResponse response, Model model) {
		Page<Join> page = joinService.findPage(new Page<Join>(request, response), join); 
		model.addAttribute("page", page);
		return "modules/ems/joinList";
	}

	@RequiresPermissions("ems:join:view")
	@RequestMapping(value = "form")
	public String form(Join join, Model model, RedirectAttributes redirectAttributes) {
		
		if(null != join && join.getDelFlag().equals(BaseEntity.DEL_FLAG_DELETE))
		{
			join = new Join();
			// model.addAttribute("message", "记录已被删除,无法修改");
			addMessage(redirectAttributes, "记录已被删除,无法修改");
			return "redirect:"+Global.getAdminPath()+"/ems/join/?repage";
		}
		model.addAttribute("join", join);
		
		Course course = new Course();
		// course.setId(join.getCourse().getId());
		List<Course> courses = this.courseService.findList(course);
		
		model.addAttribute("courses", courses);
		
		// 查询大类列表
		Mdict mdict = new Mdict();
		
		if(null != join.getCourse())
		{
			mdict.setType(Constant.Mdict.MDICT_COURSE_TYPE_PREFIX + join.getCourse().getSign());
			List<Mdict> bigCategories = this.mdictService.findList(mdict);
			model.addAttribute("bigCategories", bigCategories);
		}
		// 查询小类列表
		mdict.setType(mdict.getType() + "_" + join.getBigCategory());
		List<Mdict> smallCategories = this.mdictService.findList(mdict);
		
		
		model.addAttribute("smallCategories", smallCategories);
		
		return "modules/ems/joinForm";
	}

	@RequiresPermissions("ems:join:edit")
	@RequestMapping(value = "save")
	public String save(Join join, Model model, RedirectAttributes redirectAttributes) {
		if (!beanValidator(model, join)){
			return form(join, model,redirectAttributes);
		}
		joinService.save(join);
		addMessage(redirectAttributes, "保存报名信息成功");
		return "redirect:"+Global.getAdminPath()+"/ems/join/?repage";
	}
	
	@RequiresPermissions("ems:join:edit")
	@RequestMapping(value = "delete")
	public String delete(Join join, RedirectAttributes redirectAttributes) {
		joinService.delete(join);
		addMessage(redirectAttributes, "删除报名信息成功");
		return "redirect:"+Global.getAdminPath()+"/ems/join/?repage";
	}

	/**
     * 导出文件
     */
    @RequestMapping("downLoad")
    public void downLoad(Join join,String timeStamp, HttpServletRequest request, HttpServletResponse response, Model model) throws IOException{
    	
    	
    	response.setCharacterEncoding("utf-8");
    	String fileName = Global.getConfig("exportJoinsFileName");
    	fileName += DateUtils.getDate();
        // fileName = URLEncoder.encode(fileName, "UTF-8");
    	
    	// response.reset();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename="+ new String((fileName + ".xlsx").getBytes(), "iso-8859-1"));
        
        SXSSFWorkbook wb = new SXSSFWorkbook(-1);
        // turn off auto-flushing and accumulate all rows in memory  
        wb.setCompressTempFiles(true); //使用gzip压缩,减小空间占用  
        Sheet sh = wb.createSheet("报名信息");
        OutputStream out = new BufferedOutputStream(response.getOutputStream());
        try { //从数据库中得到结果  
            List<Join> list = joinService.findList(join);
            
            if(null == list || list.size() < 1)
            {
	            sh.setColumnWidth(0, 50 * 256);
	        	Row rowHeader = sh.createRow(0);
	            Cell cellHeader = rowHeader.createCell(0);
	            cellHeader.setCellValue("信息提示");
	            
	            Row row = sh.createRow(1);
	            Cell cell = row.createCell(0);  
	            cell.setCellValue("没有找到相关条件的数据。");  
	            
	            ((SXSSFSheet) sh).flushRows();
	            
	            rememberCookieToken(timeStamp,request,response);
	            //统一写出方法
	            writeWb(wb,out);
            }else
            {
	            
	            //设置每一列的宽度,注意 要乘以256,因为1代表excel中一个字符的1/256的宽度  
	            sh.setColumnWidth(0, 10 * 256); // 家长姓名
	            sh.setColumnWidth(1, 14 * 256);	// 家长电话
	            sh.setColumnWidth(2, 30 * 256); // 选手姓名
	            
	            sh.setColumnWidth(3, 5 * 256); // 选手性别
	            sh.setColumnWidth(4, 11 * 256); // 选手出生年月
	            sh.setColumnWidth(5, 5 * 256); // 选手年龄
	            
	            sh.setColumnWidth(6, 18 * 256);	// 展示类别
	            sh.setColumnWidth(7, 18 * 256);	// 组别
	            
	            sh.setColumnWidth(8, 30 * 256); // 选手籍贯
	            sh.setColumnWidth(9, 8 * 256); // 选手民族
	            sh.setColumnWidth(10, 20 * 256); // 选手身份证号码
	            
	            sh.setColumnWidth(11, 15 * 256);	// 展示方式
	            sh.setColumnWidth(12, 15 * 256); // 展示大类
	            sh.setColumnWidth(13, 15 * 256);	// 展示小类
	            
	            sh.setColumnWidth(14, 8 * 256); // 选手专业等级
	            
	            sh.setColumnWidth(15, 30 * 256);	// 推选学校
	            sh.setColumnWidth(16, 10 * 256);	// 表名状态
	            sh.setColumnWidth(17, 30 * 256); // 备注(初选地点)
	            sh.setColumnWidth(18, 20 * 256); // 报名时间
	            sh.setColumnWidth(19, 15 * 256); // 支付总金额（元）
	            Row rowHeader = sh.createRow(0);
	            /*CellStyle headerStyle = rowHeader.getRowStyle();
	            headerStyle.setAlignment(CellStyle.ALIGN_CENTER);*/
	            Cell cellHeader = rowHeader.createCell(0);
	            cellHeader.setCellValue("家长姓名");
	            cellHeader = rowHeader.createCell(1);
	            cellHeader.setCellValue("家长电话");
	            cellHeader = rowHeader.createCell(2);
	            cellHeader.setCellValue("姓名");
	            
	            cellHeader = rowHeader.createCell(3);
	            cellHeader.setCellValue("性别");
	            cellHeader = rowHeader.createCell(4);
	            cellHeader.setCellValue("出生年月");
	            cellHeader = rowHeader.createCell(5);
	            cellHeader.setCellValue("年龄");
	            
	            cellHeader = rowHeader.createCell(6);
	            cellHeader.setCellValue("展示类别");
	            cellHeader = rowHeader.createCell(7);
	            cellHeader.setCellValue("组别");
	            
	            cellHeader = rowHeader.createCell(8);
	            cellHeader.setCellValue("籍贯");
	            cellHeader = rowHeader.createCell(9);
	            cellHeader.setCellValue("民族");
	            cellHeader = rowHeader.createCell(10);
	            cellHeader.setCellValue("身份证号码");
	            
	            cellHeader = rowHeader.createCell(11);
	            cellHeader.setCellValue("展示方式");
	            cellHeader = rowHeader.createCell(12);
	            cellHeader.setCellValue("展示大类");
	            cellHeader = rowHeader.createCell(13);
	            cellHeader.setCellValue("展示小类");
	            
	            cellHeader = rowHeader.createCell(14);
	            cellHeader.setCellValue("专业等级");
	            
	            cellHeader = rowHeader.createCell(15);
	            cellHeader.setCellValue("推选学校");
	            cellHeader = rowHeader.createCell(16);
	            cellHeader.setCellValue("报名状态");
	            cellHeader = rowHeader.createCell(17);
	            cellHeader.setCellValue("备注(初选地点)");
	            cellHeader = rowHeader.createCell(18);
	            cellHeader.setCellValue("报名时间");
	            cellHeader = rowHeader.createCell(19);
	            cellHeader.setCellValue("支付总金额（元）");
	            
	            
	            // 只取5000条数据
	            if(null != list && list.size() > Constant.Join.JOIN_EXPORT_MOST_ROWS)
	            {
	            	list.subList(Constant.Join.JOIN_EXPORT_MOST_ROWS, list.size()).clear();
	            }
	            
	            SimpleDateFormat simpleDateFormat = null;
	            		
	            for(int i = 0; i < list.size(); i++) {
	                Row row = sh.createRow(i+1);
	                Join j = list.get(i);
	                Cell cell = row.createCell(0);  
	                cell.setCellValue(j.getRegister());  
	                cell = row.createCell(1);  
	                cell.setCellValue(j.getMobile());  
	                cell = row.createCell(2);  
	                cell.setCellValue(j.getJoiner());
	                
	                cell = row.createCell(3);  
	                cell.setCellValue(j.getSex());
	                cell = row.createCell(4);  
	                cell.setCellValue(j.getBirth());
	                cell = row.createCell(5);  
	                cell.setCellValue(j.getAge());
	                
	                cell = row.createCell(6);  
	                cell.setCellValue(j.getCourse().getName());
	                
	                cell = row.createCell(7);  
	                cell.setCellValue(DictUtils.getDictLabel(j.getGroupType(), Constant.Dict.DICT_GROUP_TYPE, null));
	                
	                cell = row.createCell(8);  
	                cell.setCellValue(j.getAddr());
	                cell = row.createCell(9);  
	                cell.setCellValue(j.getNation());
	                cell = row.createCell(10);  
	                cell.setCellValue(j.getIdCard());
	                
	                cell = row.createCell(11);  
	                cell.setCellValue(DictUtils.getDictLabel(j.getJoinType(), Constant.Dict.DICT_JOIN_TYPE, null));
	                
	                cell = row.createCell(12);  
	                cell.setCellValue(j.getBigCategoryName());
	                cell = row.createCell(13);  
	                cell.setCellValue(j.getSmallCategoryName());
	                
	                cell = row.createCell(14);  
	                cell.setCellValue(j.getLevel());
	                
	                cell = row.createCell(15);  
	                cell.setCellValue(j.getSchool());
	                cell = row.createCell(16);  
	                cell.setCellValue("-1".equals(j.getOrder().getStatus())?"订单失效":"0".equals(j.getOrder().getStatus())?"待支付":"1".equals(j.getOrder().getStatus())?"已支付":"支付失败");
	                
	                cell = row.createCell(17);  
	                cell.setCellValue(j.getRemarks());
	                
	                if(null != j.getCreateDate())
	                {
		                simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		                cell = row.createCell(18);  
		                cell.setCellValue(simpleDateFormat.format(j.getCreateDate()));
	                }
	                cell = row.createCell(19);  
	                cell.setCellValue(j.getOrder().getMoney().doubleValue()); 
	                // cell.setCellValue(simpleDateFormat.format(list.get(rownum - 1).getCreateTime()));
	      
	                // manually control how rows are flushed to disk  
	                if(i > 0 && (i % 1000 == 0)) { // ((SXSSFSheet)sh).flushRows(100); // retain 100 last rows and flush all others  
	                    ((SXSSFSheet) sh).flushRows();  
	                    //is a shortcut for ((SXSSFSheet)sh).flushRows(0),  
	                    // this method flushes all rows  
	                }  
	            }
	            
	            ((SXSSFSheet) sh).flushRows();
	            
	            rememberCookieToken(timeStamp,request,response);
	            //统一写出方法
	            writeWb(wb,out);
	            
	            // 导出后删除相关数据
	            int rows = this.joinService.deleteBatch(list);
	            if(rows == list.size())
	            {
	            	System.out.println("导出数据成功，删除数据成功。条数：" + rows);
	            	logger.info("导出数据成功，删除数据成功。条数：" + rows);
	            }
	            else
	            {
	            	System.out.println("导出数与删除数据不一致。导出条数：" + list.size() + "，删除条数：" + rows);
	            	logger.info("导出数与删除数据不一致。导出条数：" + list.size() + "，删除条数：" + rows);
	            }
            }
        } catch(Exception e) {
        	sh.setColumnWidth(0, 50 * 256);
        	Row rowHeader = sh.createRow(0);
            Cell cellHeader = rowHeader.createCell(0);
            cellHeader.setCellValue("信息提示");
            
            Row row = sh.createRow(1);
            Cell cell = row.createCell(0);  
            cell.setCellValue("导出失败，请联系管理员。错误信息：" + e.getMessage());  
            
            e.printStackTrace();
            ((SXSSFSheet) sh).flushRows();
            
            rememberCookieToken(timeStamp,request,response);
            //统一写出方法
            writeWb(wb,out);
        }  
    
    }
    
    public void writeWb(SXSSFWorkbook wb,OutputStream out)
    {
    	try {
			wb.write(out);
			out.flush();
			out.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
        // dispose of temporary files backing this workbook on disk  
        wb.dispose();  
    }
    
    public void rememberCookieToken(String timeStamp, HttpServletRequest request, HttpServletResponse response)
    {
    	if(StringUtils.isNotBlank(timeStamp))
    	{
    		CookieUtils.setCookie(response, "downToken", timeStamp, 3600);
    		String cookie=request.getHeader("cookie");
    		System.out.println(CookieUtils.getCookie(request, "downToken"));
    		System.out.println(cookie);
    	}
    }
    
}